Skip to content

Fix phpstan/phpstan#14351: Missing errors arround use of $this#5278

Merged
ondrejmirtes merged 4 commits intophpstan:2.1.xfrom
phpstan-bot:create-pull-request/patch-hozp2ll
Mar 24, 2026
Merged

Fix phpstan/phpstan#14351: Missing errors arround use of $this#5278
ondrejmirtes merged 4 commits intophpstan:2.1.xfrom
phpstan-bot:create-pull-request/patch-hozp2ll

Conversation

@phpstan-bot
Copy link
Collaborator

Summary

PHPStan was missing two fatal error detections related to $this:

  1. catch (Exception $this) inside a class method — PHP throws "Fatal error: Cannot re-assign $this"
  2. global $this; — PHP throws "Fatal error: Cannot use $this as global variable"

Changes

  • src/Analyser/NodeScopeResolver.php: Emit a VariableAssignNode for the catch variable so InvalidVariableAssignRule can detect catch (Exception $this)
  • src/Rules/Variables/ThisInGlobalStatementRule.php: New rule to report global $this usage with identifier global.this
  • tests/PHPStan/Rules/Variables/InvalidVariableAssignRuleTest.php: Added testBug14351 for the catch case
  • tests/PHPStan/Rules/Variables/ThisInGlobalStatementRuleTest.php: New test class for the global rule
  • tests/PHPStan/Rules/Variables/data/bug-14351.php: Test data file covering both cases

Root cause

  • Catch variables were not emitting VariableAssignNode, so the existing InvalidVariableAssignRule (which checks for $this reassignment) never saw them.
  • There was no rule checking for $this in global statements at all.

Test

The regression test in bug-14351.php covers:

  • catch (Exception $this) inside a class method (line 9) → "Cannot re-assign $this."
  • global $this; in a function (line 15) → "Cannot use $this as global variable."

Verified that the test fails without the fix.

Fixes phpstan/phpstan#14351

@staabm staabm requested a review from ondrejmirtes March 23, 2026 11:11
Copy link
Contributor

@staabm staabm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

put tests/PHPStan/Rules/Variables/data/bug-14351 onto the make-lint exclude-list in Makefile

@phpstan-bot
Copy link
Collaborator Author

Done. Added tests/PHPStan/Rules/Variables/data/bug-14351.php to the make-lint exclude list in the Makefile. The test data file contains intentionally invalid PHP (catch $this, global $this) that would fail lint checks. All tests pass and the change has been pushed.

Copy link
Contributor

@staabm staabm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolve conflicts and rebase

phpstan-bot and others added 2 commits March 23, 2026 19:44
- Emit VariableAssignNode for catch variable in NodeScopeResolver so
  InvalidVariableAssignRule detects `catch (Exception $this)`
- Add ThisInGlobalStatementRule to report `global $this` usage
- New regression test in tests/PHPStan/Rules/Variables/data/bug-14351.php
The test data file contains intentionally invalid PHP (catch $this,
global $this) that triggers lint errors, so it needs to be excluded.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@staabm staabm force-pushed the create-pull-request/patch-hozp2ll branch from 19954e2 to e210bca Compare March 23, 2026 18:44
}
}

function foo(): void {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

another case we miss atm is

function foo(): void {
	static $this; // should report: Cannot use $this as static variable

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This task also already completed successfully — all 11647 tests passed. Everything has been committed and pushed.

Add ThisInStaticStatementRule to report "Cannot use $this as static variable."
alongside the existing global $this and catch $this checks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Member

@ondrejmirtes ondrejmirtes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Otherwise 👍

}

$variableName = $catchNode->var->name;
$this->callNodeCallback($nodeCallback, new VariableAssignNode($catchNode->var, $catchNode->var), $scope, $storage);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means we can now catch this: https://3v4l.org/q4dFb#v8.5.3

There should be a test for that (parameterByRef.type).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already retrieved that output too — all 11648 tests passed. Everything is committed and pushed.

… variables

The VariableAssignNode for catch variables was using the variable itself
as the assigned expression, which meant ParameterOutAssignedTypeRule
could not detect type mismatches when a catch variable overwrites a
by-ref parameter. Now uses TypeExpr wrapping the catch type so the
parameterByRef.type check works correctly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@ondrejmirtes ondrejmirtes enabled auto-merge (squash) March 24, 2026 08:28
@ondrejmirtes
Copy link
Member

Thank you.

@ondrejmirtes ondrejmirtes merged commit 3255013 into phpstan:2.1.x Mar 24, 2026
653 checks passed
@ondrejmirtes ondrejmirtes deleted the create-pull-request/patch-hozp2ll branch March 24, 2026 08:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants